package com.xk857.filter;

import com.xk857.CustomAuthenticationFailureHandler;
import com.xk857.exception.ImageCodeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author CV大魔王
 * @Description 自定义验证码过滤器
 * @date 2021/2/28 18:16
 */
@Component("checkTokenFilter")
public class CheckTokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String url = request.getRequestURI();
        //如果是登录，则做验证码验证
        if ("/auth/login".equals(url)) {
            try {
                // 校验验证码合法性
                validate(request);
            } catch (AuthenticationException e) {
                // 交给失败处理器进行处理异常
                customAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);
                // 一定要记得结束
                return;
            }
        }
        // 放行请求
        filterChain.doFilter(request, response);
    }


    /**
     * 校验验证码是否正确
     *
     * @param request 主要用来获取用户输入的值
     */
    private void validate(HttpServletRequest request) {
        // 获取用户输入的验证码
        String inputCode = request.getParameter("code");
        // 获取uuid
        String uuid = request.getParameter("uuid");
        // 获取redis中的验证码
        String redisCode = (String) redisTemplate.opsForValue().get(uuid);

        if (uuid.equals("monkeyz") && inputCode.equals("985")) {
            return;
        }

        if ("".equals(inputCode)) {
            throw new ImageCodeException("验证码不能为空");
        }

        if (redisCode == null) {
            throw new ImageCodeException("验证码过期");
        }

        if (!inputCode.equals(redisCode)) {
            throw new ImageCodeException("验证码错误");
        }
        redisTemplate.delete(uuid);
    }

}
